<!DOCTYPE html>
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<style type="text/css">
		body,
		html,
		#allmap {
			width: 100%;
			height: 100%;
			overflow: hidden;
			margin: 0;
			font-family: "微软雅黑";
		}
		#dashboard {
            position: fixed;
            top: 0;
            height: 100%;
            width: 14%;
            right: 0;
            z-index: 99;
            background-color: white;
            opacity: 80%;
        }

        .block {
            height: 20%;
            width: 100%;
            background-color: white;
        }
	</style>
	<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/echarts/5.0.0/echarts.min.js"></script>
	<link rel="shortcut icon" href="./favicon.ico">
	<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=DUS3zgcXlPG5gyjfdSra8NfpOblj7Ggr"></script>
	<!-- <link rel="icon" href="./favicon.ico" mce_href="./favicon.ico" type="image/x-icon">  
    <link rel="shortcut icon" href="./favicon.ico" mce_href="./favicon.ico" type="image/x-icon">   -->
	<title>船舶交通流仿真平台</title>
</head>

<body>
	<div id="allmap"></div>
    <div id="dashboard">
        <div id="shipInfo" class="block">
            <table style="text-align:left;height:100%;">
                <tbody>
                    <tr>
                        <th>shipName：皖安顺9988</th>
                        <th id="shipName"></th>
                    </tr>
                    <tr>
                        <th>MMSI：413823508</th>
                        <th id="MMSI"></th>
                    </tr>
                    <tr>
                        <th>SimClock：270</th>
                        <th id="simClock"></th>
                    </tr>
                    <tr>
                        <th>LON：118.32E</th>
                        <th id="LON"></th>
                    </tr>
                    <tr>
                        <th>LAT：31.509N</th>
                        <th id="LAT"></th>
                    </tr>
                </tbody>
            </table>
        </div>
        <div id="VO" class="block">
            <svg xmlns="http://www.w3.org/2000/svg" viewbox="-100 -100 200 200">
                <text x="-50" y="-60" font-family="Verdana" font-size="12">Velocity Obstacle</text>
                <circle id="Circle" cx="0" cy="0" r="50" stroke="white" stroke-width="0" fill="white" />

                <path id="A2" stroke="#F4D03F" stroke-width="1" fill="#F4D03F" />
                <path id="A3" stroke="#F4D03F" stroke-width="1" fill="#F4D03F" />
                <!-- <path id="A4" stroke="#2ECC71" stroke-width="1" fill="#2ECC71" /> -->
                <path id="A1" stroke="#E74C3C" stroke-width="0" fill="#E74C3C" />

                <defs>
                    <marker id="arrow" markerWidth="4" markerHeight="4" refx="2" refy="2" orient="auto"
                        markerUnits="strokeWidth">
                        <path id="arrow_body" d="M 0 0 L 0 4 L 4 2 Z" fill="#212F3D" />
                    </marker>
                </defs>>
                <line id="speedLine" x1="0" y1="0" y2="0" stroke="#212F3D" marker-end="url(#arrow)" stroke-width="1.5"
                    transform="rotate(20)" />
                <!-- 绘制白色下半圆 遮住原来的半圆 -->
                <path id="Cover" stroke-width="2" stroke="white" fill="white" />
                <circle id="P1" r="1" stroke="black" stroke-width="2" />

                <!-- 遮瑕用的 -->
                <circle id="poly" r="5" stroke="transparent" fill="white" />
            </svg>
        </div>
        <div id="riskValue" class="block">Risk value</div>
        <div id="TCPA" class="block"> TCPA</div>
        <div id="DCPA" class="block"> hello</div>
    </div>
</body>

</html>
<script type="text/javascript">
	// 百度地图API功能
	var map = new BMap.Map("allmap");
	// map.centerAndZoom(new BMap.Point(118.765052, 32.137083), 14);
	map.centerAndZoom(new BMap.Point(118.6224279, 31.94938), 17);
	map.enableScrollWheelZoom(); // 使能缩放

// DCPA
	var chartDomDcpa = document.getElementById("DCPA");
        var myChartDcpa = echarts.init(chartDomDcpa);
        var optionDcpa;
        optionDcpa = {
            series: [{
                min: -10000,
                max: 10000,
                type: 'gauge',
                progress: {
                    show: true,
                    width: 8
                },
                axisLine: {
                    lineStyle: {
                        width: 8
                    }
                },
                axisTick: {
                    show: false
                },
                splitLine: {
                    show: true,
                    length: 5,
                    distance: 2,
                    lineStyle: {
                        width: 2,
                        color: '#999'
                    }
                },
                axisLabel: {
                    distance: 10,
                    color: '#999',
                    fontSize: 10
                },
                anchor: {
                    show: true,
                    showAbove: true,
                    size: 10,
                    itemStyle: {
                        borderWidth: 5
                    }
                },
                detail: {
                    valueAnimation: false,
                    fontSize: 15,
                    offsetCenter: [0, '80%']
                },
                data: [{
                    value: 1930.74,
                    name: "DCPA",
                    title: {
                        show: true,
                        offsetCenter: [0, "-120%"],
                        fontSize: 15
                    },
                    fontSize: 15
                }]
            }]
        };
        optionDcpa && myChartDcpa.setOption(optionDcpa);

        // TCPA
        var chartDomTcpa = document.getElementById("TCPA");
        var myChartTcpa = echarts.init(chartDomTcpa);
        var optionTcpa;
        optionTcpa = {
            series: [{
                min: -2000,
                max: 2000,
                type: 'gauge',
                progress: {
                    show: true,
                    width: 8,
                    itemStyle: {
                        color: "#7DCEA0"
                    }
                },
                axisLine: {
                    lineStyle: {
                        width: 8
                    }
                },
                axisTick: {
                    show: false
                },
                splitLine: {
                    show: true,
                    length: 5,
                    distance: 2,
                    lineStyle: {
                        width: 2,
                        color: '#999'
                    }
                },
                axisLabel: {
                    distance: 10,
                    color: '#999',
                    fontSize: 10
                },
                anchor: {
                    show: true,
                    showAbove: true,
                    size: 10,
                    itemStyle: {
                        borderWidth: 5,
                        bprderColor: "#7DCEA0"
                    }
                },
                pointer: {
                    itemStyle: {
                        color: '#7DCEA0'
                    }
                },
                detail: {
                    valueAnimation: false,
                    fontSize: 15,
                    offsetCenter: [0, '80%']
                },
                data: [{
                    value: 502.28,
                    name: "TCPA",
                    title: {
                        show: true,
                        offsetCenter: [0, "-120%"],
                        fontSize: 15
                    },
                    fontSize: 15
                }]
            }]
        };
        optionTcpa && myChartTcpa.setOption(optionTcpa);

        // risk value
        var chartDomRisk = document.getElementById("riskValue");
        var myChartRisk = echarts.init(chartDomRisk);
        var optionRisk;
        optionRisk = {
            series: [{
                min: 0,
                max: 1,
                type: 'gauge',
                progress: {
                    show: true,
                    width: 8,
                    itemStyle: {
                        color: "#D98880"
                    }
                },
                axisLine: {
                    lineStyle: {
                        width: 8
                    }
                },
                axisTick: {
                    show: false
                },
                splitLine: {
                    show: true,
                    length: 5,
                    distance: 2,
                    lineStyle: {
                        width: 2,
                        color: '#999'
                    }
                },
                axisLabel: {
                    distance: 10,
                    color: '#999',
                    fontSize: 10
                },
                anchor: {
                    show: true,
                    showAbove: true,
                    size: 10,
                    itemStyle: {
                        borderWidth: 5,
                        bprderColor: "#D98880"
                    }
                },
                pointer: {
                    itemStyle: {
                        color: '#D98880'
                    }
                },
                detail: {
                    valueAnimation: false,
                    fontSize: 15,
                    offsetCenter: [0, '80%']
                },
                data: [{
                    value: 0.1074,
                    name: "Risk",
                    title: {
                        show: true,
                        offsetCenter: [0, "-120%"],
                        fontSize: 15
                    },
                    fontSize: 15
                }]
            }]
        };
        optionRisk && myChartRisk.setOption(optionRisk);

        // 绘制VO
        function parseArgs(args) {
            let points = [];
            // 设定调节图形大小的系数
            let k = 2.5;
            let res = args.VOPxy;
            // console.log(args);
            for (let index in res) {
                points.push({
                    lon: (res[index][0] * k),
                    lat: (res[index][1] * k)
                })
            }
            if (args.speed < 4) {
                tspeed = args.speed * 4 * k - 2;
            } else if (args.speed < 8) {
                tspeed = args.speed * 2 * k - 2;
            } else {
                tspeed = args.speed * k - 2;
            }
            return {
                k: k,
                points: points,
                radius: args.radius * k,
                speed: tspeed,
                heading: args.head - 90
            };
        }
        function drawVo(args) {
            // 判断状态
            let status = args.status;
            if (status == 0) {

            } else if (status == 1) {

            } else if (status == -1) {

            }
            let tmp = parseArgs(args);
            let k = tmp.k;
            let points = tmp.points;
            let radius = tmp.radius;
            let speed = tmp.speed;
            let heading = tmp.heading;

            let p0 = points[0];
            let p1 = points[1];
            let p2 = points[2];
            let p3 = points[3];
            let p4 = points[4];
            let p5 = points[5];
            let p6 = points[6];
            let p7 = points[7];
            let p8 = points[8];
            let normPointArray = [p0, p1, p2, p3, p4, p5, p6, p7, p8];

            // 下面开始绘图
            // 绘制圆 可省略
            let Circle = document.getElementById("Circle");
            Circle.setAttribute("fill", "#2ECC71");
            // Circle.style.cx = normPointArray[1].lon.toString();
            // Circle.style.cy = normPointArray[1].lat.toString();
            // Circle.style.r = radius;
            let poly = document.getElementById("poly");
            poly.style.fill = "transparent";

            // 分别绘制4个区域
            let A2 = document.getElementById("A2");
            A2.setAttribute("d", `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[3].lon} ${normPointArray[3].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[5].lon} ${normPointArray[5].lat} Z`)

            let A3 = document.getElementById("A3");
            A3.setAttribute("d", `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[6].lon} ${normPointArray[6].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[4].lon} ${normPointArray[4].lat} Z`)

            // let A4 = document.getElementById("A4");
            // A4.setAttribute("d", `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[4].lon} ${normPointArray[4].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[3].lon} ${normPointArray[3].lat} Z`)

            let A1 = document.getElementById("A1");
            A1.setAttribute('d', `M ${normPointArray[2].lon} ${normPointArray[2].lat} L ${normPointArray[5].lon} ${normPointArray[5].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[6].lon} ${normPointArray[6].lat} Z`);

            // 绘制P1 中心点
            let P1 = document.getElementById("P1");
            P1.style.cx = normPointArray[1].lon.toString();
            P1.style.cy = normPointArray[1].lat.toString();
            if (k < 2) {
                // P1.style.stroke-width = "2";
                P1.setAttribute("stroke-width", "1");
            }

            // 绘制速度矢量
            let speedLine = document.getElementById("speedLine");
            speedLine.setAttribute("x2", `${speed}`);
            speedLine.setAttribute("transform", `rotate(${heading})`);

            // 绘制下半圆遮盖物
            // let Cover = document.getElementById("Cover");
            // Cover.setAttribute("d", `M ${normPointArray[1].lon} ${normPointArray[1].lat} L ${normPointArray[7].lon} ${normPointArray[7].lat} A ${radius} ${radius} 0 0 0 ${normPointArray[8].lon} ${normPointArray[8].lat}`);

        }
        let args = {
            "VOPxy": [[94.52317246766864, 111.3763884589862], [0, 0], [5.000000000710581, -8.660254038167059], [-17.209872196534498, 10.189224651815314], [12.851883956418277, -15.324133866577933], [15.998927009258402, 12.001430521367292], [19.999635936012922, -0.12067486577087888], [6.840402866906618, -18.79385241669232], [-6.840402865397154, 18.793852414984354]],
            "radius": 20, "speed": 15, "head": 115, "status": 0
        };
        drawVo(args);

	var myIcon1 = new BMap.Icon("./icons/1-15-30.svg", new BMap.Size(35, 70), {    //小车图片
		imageOffset: new BMap.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
	});	
	var myIcon2 = new BMap.Icon("./icons/2-15-25.svg", new BMap.Size(35, 70), {    //小车图片
		imageOffset: new BMap.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
	});	
	var myIcon3 = new BMap.Icon("./icons/3-15-30.svg", new BMap.Size(35, 70), {    //小车图片
		imageOffset: new BMap.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
	});
	var myIcon4 = new BMap.Icon("./icons/4-15-25.svg", new BMap.Size(35, 70), {    //小车图片
		imageOffset: new BMap.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
	});
	var myIcon5 = new BMap.Icon("./icons/5-15-25.svg", new BMap.Size(35, 70), {    //小车图片
		//offset: new BMap.Size(0, -5),    //相当于CSS精灵
		imageOffset: new BMap.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
	});
	var myIcon6 = new BMap.Icon("./icons/6-15-25.svg", new BMap.Size(35, 70), {    //小车图片
		//offset: new BMap.Size(0, -5),    //相当于CSS精灵
		imageOffset: new BMap.Size(0, 0)    //图片的偏移量。为了是图片底部中心对准坐标点。
	});
	var myIcon = [myIcon1, myIcon2, myIcon3, myIcon4, myIcon5, myIcon6];
	// var driving2 = new BMap.DrivingRoute(map, {renderOptions:{map: map, autoViewport: true}});    //驾车实例
	// driving2.search(myP1, myP2);    //显示一条公交线路
	function get_path(start_point, end_point, rd, delta = 0.0002) {
		// 在路径上均匀采样 uniform_sampling, 采样间隔为delta. 横纵坐标(经纬度)按照相似三角形计算.
		// console.log("get_path was called.");
		let distance = Math.hypot(
			end_point[0] - start_point[0],
			end_point[1] - start_point[1]
		)
		if (distance > delta) {
			path = [];
			let N = Math.abs(parseInt(distance / delta));
			for (let i = 0; i < N; i++) {
				// 根据形似三角形计算某个场景下经纬度的delta
				delta_x = (delta / distance) * (end_point[0] - start_point[0]);
				delta_y = (delta / distance) * (end_point[1] - start_point[1]);
				// N从0到N-1 包含起点, 不含终点
				path.push(new BMap.Point(start_point[0] + delta_x * i + rd, start_point[1] + delta_y * i));
			}
			path.push(new BMap.Point(end_point[0] + rd, end_point[1]));
		} else {
			path = [new BMap.Point(start_point[0] + rd, start_point[1]), new BMap.Point(end_point[0] + rd, end_point[1])];
		}
		return path
	}
	function get_line(my_line, rd) {
		// console.log("get_line was called.");
		let line = [];
		let td = rd;
		for (let k = 0; k < my_line.length -1; k++) {
			let path = get_path(my_line[k], my_line[k+1], rd);
			// console.log(path[0]);
			for (let n=0; n < path.length; n++) {
				// console.log(path[n]);
				line.push(path[n]);
			}
		}
		return line;
	}
	function get_angle(lng1, lat1, lng2, lat2, flag = "up"){		
		// console.log("called get angle.")
		// console.log(lng1, lat1)
		if(flag == "up"){
			var mod = function (n, m) {
			var remain = n % m;
			return 180 + Math.floor(remain >= 0 ? remain : remain + m);
			};
		}else{
			var mod = function (n, m) {
			var remain = n % m;
			return Math.floor(remain >= 0 ? remain : remain + m);
			};
		}

		let x = Math.abs(lng1 - lng2);
		let y = Math.abs(lat1 - lat2);
		let z = Math.sqrt(x * x + y * y);
		// console.log(Math.asin(y / z) / Math.PI);
		let angle = Math.round(Math.asin(y / z) / Math.PI * 180);
		// console.log(mod(90 - angle, 360));
		return mod(90 - angle, 360)
	}
	window.run = function (re_speed) {
		// 预设中心航线
		let line = [[118.765052, 32.137083], [118.757578, 32.130112], [118.748092, 32.120204], [118.739253, 32.109989], [118.730342, 32.098917], [118.724449, 32.092249], [118.717047, 32.084723], [118.71101, 32.078665], [118.706698, 32.075178], [118.701811, 32.06967], [118.698074, 32.063673], [118.694194, 32.054859], [118.690313, 32.043107], [118.687151, 32.034537], [118.682049, 32.024496], [118.67364, 32.00683], [118.669185, 31.997185], [118.663579, 31.988089], [118.65783, 31.980157], [118.649135, 31.971795], [118.639864, 31.96426], [118.632893, 31.958133], [118.623695, 31.951147], [118.616221, 31.946552], [118.606303, 31.941894], [118.596674, 31.937482], [118.580935, 31.929208], [118.572671, 31.923017], [118.566059, 31.915171], [118.556142, 31.904198], [118.551399, 31.898741], [118.545291, 31.893468], [118.534223, 31.883167], [118.529624, 31.877464], [118.525169, 31.870718], [118.521216, 31.861702], [118.518557, 31.851397], [118.51712, 31.844035], [118.515251, 31.836366], [118.513526, 31.83244], [118.511155, 31.828451], [118.505693, 31.821149]];
		// 随机生成相对航线的偏移量
		let rd = (Math.random() * 2 - 1) * 0.002;
		// 生成偏移的航线
		let pts = get_line(line, rd);
		// 航线的“步数”
		let paths = pts.length;
		// 从Icon列表中随机选一个作为当前船的Icon
		let ind = Math.floor(Math.random() * myIcon.length);
		// 创建图标
		let carMk = new BMap.Marker(pts[0], {
			icon: myIcon[ind],
			rotation: 225,
		});
		// 向地图添加图标
		map.addOverlay(carMk);
		let i = 1;
		// 设定当前船舶对象更新下一个位置的时间unisp，这个值越小，速度越快
		let unisp = re_speed + Math.random() * 100;
		// 定义船舶更新坐标位置的函数
		function resetMkPoint(i) {
			// 依据商议时刻的坐标和当前坐标计算角度
			let angle = get_angle(pts[i-1].lng, pts[i-1].lat, pts[i].lng, pts[i].lat, "up");
			carMk.setRotation(angle);
			carMk.setPosition(pts[i]);
			// 如果还没走完，unisp时间后更新下一个位置
			if (i < paths-1) {				
				setTimeout(function () {
					i++;
					resetMkPoint(i);
				}, unisp);
			}
			// 如果走完了，将其从地图中移除
			else{
				map.removeOverlay(carMk);
			}
		}
		// 网面加载500ms后调用上述函数
		setTimeout(function () {
			resetMkPoint(1);
		}, 500);
	}

	window.run2 = function (re_speed) {
		let line = [[118.513059, 31.789388], [118.518809, 31.793869], [118.524198, 31.799332], [118.528295, 31.804795], [118.537206, 31.819769], [118.543961, 31.834863], [118.547698, 31.849587], [118.549351, 31.857439], [118.550285, 31.864308], [118.551219, 31.871546], [118.552297, 31.878414], [118.556322, 31.890801], [118.560274, 31.898772], [118.565017, 31.90619], [118.57091, 31.914589], [118.577594, 31.921209], [118.584996, 31.926726], [118.591967, 31.930403], [118.60907, 31.937758], [118.624593, 31.945847], [118.638966, 31.957367], [118.654345, 31.972806], [118.662537, 31.981382], [118.668646, 31.989406], [118.673173, 31.998042], [118.676623, 32.005636], [118.68424, 32.019475], [118.693727, 32.03723], [118.700338, 32.049106], [118.707093, 32.062204], [118.714567, 32.074076], [118.718879, 32.080073], [118.723191, 32.085213], [118.732533, 32.09439], [118.743169, 32.106747], [118.750499, 32.115923], [118.756105, 32.120449], [118.766166, 32.127665], [118.775077, 32.132925]];
		// let line2 = [[118.766052, 32.137083], [118.758578, 32.130112], [118.749092, 32.120204], [118.7402530, 32.109989], [118.731342, 32.098917], [118.7254490, 32.092249], [118.718047, 32.084723], [118.71201, 32.078665], [118.707698, 32.075178], [118.7028110, 32.06967], [118.6990740, 32.063673], [118.695194, 32.054859], [118.69131300000001, 32.043107], [118.688151, 32.034537], [118.6830490, 32.024496], [118.674640, 32.00683], [118.670185, 31.997185], [118.664579, 31.988089], [118.658830, 31.980157], [118.650135, 31.971795], [118.6408640, 31.96426], [118.633893, 31.958133], [118.624695, 31.951147], [118.617221, 31.946552], [118.607303, 31.941894], [118.597674, 31.937482], [118.581935, 31.929208], [118.573671, 31.923017], [118.567059, 31.915171], [118.557142, 31.904198], [118.5523990, 31.898741], [118.5462910, 31.893468], [118.535223, 31.883167], [118.530624, 31.877464], [118.5261690, 31.870718], [118.522216, 31.861702], [118.519557, 31.851397], [118.518120, 31.844035], [118.5162510, 31.836366], [118.514526, 31.83244], [118.512155, 31.828451], [118.506693, 31.821149]];

		// var pts = get_path([118.765052, 32.137083], [118.757578, 32.130112]);
		// var pts = get_path(line[0], line[1]);
		let rd = (Math.random() * 2 - 1) * 0.002;
		let pts = get_line(line, rd);
		let paths = pts.length;
		console.log("path length:", paths);
		let ind = Math.floor(Math.random() * myIcon.length);

		let carMk = new BMap.Marker(pts[0], {
			icon: myIcon[ind],
			rotation: 45,
		});

		map.addOverlay(carMk);
		let i = 1;
		let unisp = re_speed + Math.random() * 100;
		function resetMkPoint(i) {
			// console.log(i);
			let angle = get_angle(pts[i-1].lng, pts[i-1].lat, pts[i].lng, pts[i].lat, "down");
			carMk.setRotation(angle);
			carMk.setPosition(pts[i]);
			if (i < paths-1) {				
				setTimeout(function () {
					i++;
					resetMkPoint(i);
				}, unisp);
			}else{
				map.removeOverlay(carMk);
			}
		}
		setTimeout(function () {
			resetMkPoint(1);
		}, 500);
	}

	window.run3 = function(){
		function get_angle(lng1, lat1, lng2, lat2, flag = "up"){		
			// console.log("called get angle.")
			// console.log(lng1, lat1)
			if(flag == "up"){
				var mod = function (n, m) {
				var remain = n % m;
				return 180 + Math.floor(remain >= 0 ? remain : remain + m);
				};
			}else{
				var mod = function (n, m) {
				var remain = n % m;
				return Math.floor(remain >= 0 ? remain : remain + m);
				};
			}

			let x = Math.abs(lng1 - lng2);
			let y = Math.abs(lat1 - lat2);
			let z = Math.sqrt(x * x + y * y);
			// console.log(Math.asin(y / z) / Math.PI);
			let angle = Math.round(Math.asin(y / z) / Math.PI * 180);
			// console.log(mod(90 - angle, 360));
			return mod(90 + angle, 360) -180;
			}
		// let line = [];
		$.get('./NSferry.json', function(lines){
			// let line = [[118.765052, 32.137083], [118.757578, 32.130112], [118.748092, 32.120204], [118.739253, 32.109989], [118.730342, 32.098917], [118.724449, 32.092249], [118.717047, 32.084723], [118.71101, 32.078665], [118.706698, 32.075178], [118.701811, 32.06967], [118.698074, 32.063673], [118.694194, 32.054859], [118.690313, 32.043107], [118.687151, 32.034537], [118.682049, 32.024496], [118.67364, 32.00683], [118.669185, 31.997185], [118.663579, 31.988089], [118.65783, 31.980157], [118.649135, 31.971795], [118.639864, 31.96426], [118.632893, 31.958133], [118.623695, 31.951147], [118.616221, 31.946552], [118.606303, 31.941894], [118.596674, 31.937482], [118.580935, 31.929208], [118.572671, 31.923017], [118.566059, 31.915171], [118.556142, 31.904198], [118.551399, 31.898741], [118.545291, 31.893468], [118.534223, 31.883167], [118.529624, 31.877464], [118.525169, 31.870718], [118.521216, 31.861702], [118.518557, 31.851397], [118.51712, 31.844035], [118.515251, 31.836366], [118.513526, 31.83244], [118.511155, 31.828451], [118.505693, 31.821149]];
			// let line2 = [[118.766052, 32.137083], [118.758578, 32.130112], [118.749092, 32.120204], [118.7402530, 32.109989], [118.731342, 32.098917], [118.7254490, 32.092249], [118.718047, 32.084723], [118.71201, 32.078665], [118.707698, 32.075178], [118.7028110, 32.06967], [118.6990740, 32.063673], [118.695194, 32.054859], [118.69131300000001, 32.043107], [118.688151, 32.034537], [118.6830490, 32.024496], [118.674640, 32.00683], [118.670185, 31.997185], [118.664579, 31.988089], [118.658830, 31.980157], [118.650135, 31.971795], [118.6408640, 31.96426], [118.633893, 31.958133], [118.624695, 31.951147], [118.617221, 31.946552], [118.607303, 31.941894], [118.597674, 31.937482], [118.581935, 31.929208], [118.573671, 31.923017], [118.567059, 31.915171], [118.557142, 31.904198], [118.5523990, 31.898741], [118.5462910, 31.893468], [118.535223, 31.883167], [118.530624, 31.877464], [118.5261690, 31.870718], [118.522216, 31.861702], [118.519557, 31.851397], [118.518120, 31.844035], [118.5162510, 31.836366], [118.514526, 31.83244], [118.512155, 31.828451], [118.506693, 31.821149]];

			// var pts = get_path([118.765052, 32.137083], [118.757578, 32.130112]);
			// var pts = get_path(line[0], line[1]);
			// 随机取一条结果
			let idl = Math.floor(Math.random() * lines.length);
			line = lines[idl];

			// let rd = (Math.random() * 2 - 1) * 0.002;
			let rd = 0;
			let pts = get_line(line, rd);
			// console.log(pts);
			let paths = pts.length;
			console.log("path length:", paths);
			let ind = Math.floor(Math.random() * myIcon.length);

			let carMk = new BMap.Marker(pts[0], {
				icon: myIcon[ind],
				rotation: 120,
			});

			map.addOverlay(carMk);
			let i = 1;
			let unisp = 800 + Math.random() * 100;
			function resetMkPoint(i) {
				// console.log(i);
				let angle = get_angle(pts[i-1].lng, pts[i-1].lat, pts[i].lng, pts[i].lat, "up");
				carMk.setRotation(angle);
				carMk.setPosition(pts[i]);
				if (i < paths-1) {				
					setTimeout(function () {
						i++;
						resetMkPoint(i);
					}, unisp);
				}else{
					map.removeOverlay(carMk);
				}
			}
			setTimeout(function () {
				resetMkPoint(1);
			}, 500);
		});
	}
	window.run4 = function(){
		function get_angle(lng1, lat1, lng2, lat2, flag = "up"){		
			// console.log("called get angle.")
			// console.log(lng1, lat1)
			if(flag == "up"){
				var mod = function (n, m) {
				var remain = n % m;
				return 180 + Math.floor(remain >= 0 ? remain : remain + m);
				};
			}else{
				var mod = function (n, m) {
				var remain = n % m;
				return Math.floor(remain >= 0 ? remain : remain + m);
				};
			}

			let x = Math.abs(lng1 - lng2);
			let y = Math.abs(lat1 - lat2);
			let z = Math.sqrt(x * x + y * y);
			// console.log(Math.asin(y / z) / Math.PI);
			let angle = Math.round(Math.asin(y / z) / Math.PI * 180);
			// console.log(mod(90 - angle, 360));
			return mod(90 + angle, 360)
			}
		// let line = [];
		$.get('./SNferry.json', function(lines){
			// let line = [[118.765052, 32.137083], [118.757578, 32.130112], [118.748092, 32.120204], [118.739253, 32.109989], [118.730342, 32.098917], [118.724449, 32.092249], [118.717047, 32.084723], [118.71101, 32.078665], [118.706698, 32.075178], [118.701811, 32.06967], [118.698074, 32.063673], [118.694194, 32.054859], [118.690313, 32.043107], [118.687151, 32.034537], [118.682049, 32.024496], [118.67364, 32.00683], [118.669185, 31.997185], [118.663579, 31.988089], [118.65783, 31.980157], [118.649135, 31.971795], [118.639864, 31.96426], [118.632893, 31.958133], [118.623695, 31.951147], [118.616221, 31.946552], [118.606303, 31.941894], [118.596674, 31.937482], [118.580935, 31.929208], [118.572671, 31.923017], [118.566059, 31.915171], [118.556142, 31.904198], [118.551399, 31.898741], [118.545291, 31.893468], [118.534223, 31.883167], [118.529624, 31.877464], [118.525169, 31.870718], [118.521216, 31.861702], [118.518557, 31.851397], [118.51712, 31.844035], [118.515251, 31.836366], [118.513526, 31.83244], [118.511155, 31.828451], [118.505693, 31.821149]];
			// let line2 = [[118.766052, 32.137083], [118.758578, 32.130112], [118.749092, 32.120204], [118.7402530, 32.109989], [118.731342, 32.098917], [118.7254490, 32.092249], [118.718047, 32.084723], [118.71201, 32.078665], [118.707698, 32.075178], [118.7028110, 32.06967], [118.6990740, 32.063673], [118.695194, 32.054859], [118.69131300000001, 32.043107], [118.688151, 32.034537], [118.6830490, 32.024496], [118.674640, 32.00683], [118.670185, 31.997185], [118.664579, 31.988089], [118.658830, 31.980157], [118.650135, 31.971795], [118.6408640, 31.96426], [118.633893, 31.958133], [118.624695, 31.951147], [118.617221, 31.946552], [118.607303, 31.941894], [118.597674, 31.937482], [118.581935, 31.929208], [118.573671, 31.923017], [118.567059, 31.915171], [118.557142, 31.904198], [118.5523990, 31.898741], [118.5462910, 31.893468], [118.535223, 31.883167], [118.530624, 31.877464], [118.5261690, 31.870718], [118.522216, 31.861702], [118.519557, 31.851397], [118.518120, 31.844035], [118.5162510, 31.836366], [118.514526, 31.83244], [118.512155, 31.828451], [118.506693, 31.821149]];

			// var pts = get_path([118.765052, 32.137083], [118.757578, 32.130112]);
			// var pts = get_path(line[0], line[1]);
			// 随机取一条结果
			let idl = Math.floor(Math.random() * lines.length);
			line = lines[idl];

			// let rd = (Math.random() * 2 - 1) * 0.002;
			let rd = 0;
			let pts = get_line(line, rd);
			// console.log(pts);
			let paths = pts.length;
			console.log("path length:", paths);
			let ind = Math.floor(Math.random() * myIcon.length);

			let carMk = new BMap.Marker(pts[0], {
				icon: myIcon[ind],
				rotation: 315,
			});

			map.addOverlay(carMk);
			let i = 1;
			let unisp = 700 + Math.random() * 200;
			function resetMkPoint(i) {
				// console.log(i);
				let angle = get_angle(pts[i-1].lng, pts[i-1].lat, pts[i].lng, pts[i].lat, "up");
				carMk.setRotation(angle);
				carMk.setPosition(pts[i]);
				if (i < paths-1) {				
					setTimeout(function () {
						i++;
						resetMkPoint(i);
					}, unisp);
				}else{
					map.removeOverlay(carMk);
				}
			}
			setTimeout(function () {
				resetMkPoint(1);
			}, 500);
		});
	}
	run3();
	// setTimeout(function () {
	// 	run();
	// 	run2();
	// }, 500);
	setInterval(function () {
		run(100);
	}, 10000 + Math.random() * 20000);
	setInterval(function () {
		run2(100);
	}, 10000 + Math.random() * 20000);
	setInterval(function () {
		run3();
	}, 50000 + Math.random() * 20000);
	setInterval(function () {
		run4();
	}, 50000 + Math.random() * 20000);

</script>